#include "head.h"
#define N 1024

typedef struct {
	int user_type;
	char action_type;
	int id;
	char name[N];
	int password;
	char sex;
	int age;
	int wage;
	char data[N];
}MSG;

#define err_log(errlog) do{                    \
							perror(errlog);    \
							exit(EXIT_FAILURE);\
							}while(0)
								
#define MENU1 printf("**********************************\n");\
			  printf("* 1. root用户  2. usr用户  3. quit *\n");\
			  printf("**********************************\n");\
			  printf("please choose: ")

#define MENU2 printf("*********************************************\n");\
			  printf("* 1. register  2. login  3. quit *\n");\
			  printf("*********************************************\n");\
			  printf("please choose: ")

#define MENU3 printf("input your ID:");\
			  scanf("%d", &msg->id);\
			  printf("input your password:");\
			  scanf("%d", &msg->password)

#define MENU4 printf("*********************************************\n");\
			  printf("* 1. query  2.insert 3. delete  4. modify  5.quit *\n");\
			  printf("*********************************************\n");\
			  printf("please choose: ")		
			  
#define MENU5 printf("add new  usrID:\n");\
			  scanf("%d", &msg->id);\
			  printf("input usrname :\n");\
			  scanf("%s", msg->name);\
			  printf("input  usrpassword:\n");\
			  scanf("%d", &msg->password);\
              getchar();\
			  printf("input sex:");\
			  scanf("%c", &msg->sex);\
			  printf("input age:");\
			  scanf("%d", &msg->age);\
			  printf("input wage:");\
			  scanf("%d", &msg->wage)
			  
#define MENU6 printf("*********************************************\n");\
              printf("*which item you want to modify*\n");\
			  printf("* 1. age  2. wage 3.back\n");\
			  printf("*********************************************\n");\
			  printf("please choose: ")		
	
#define MENU7 printf("*********************************************\n");\
			  printf("* 1. query  2. modify  3.quit *\n");\
			  printf("*********************************************\n");\
			  printf("please choose: ")			
int msglen = sizeof(MSG);

int do_login(int sockfd, MSG *msg)
{
	int ret;
    msg->action_type='L';
	MENU3;
	ret = send(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to send\n");
	}

	ret = recv(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to recv\n");
	}

	printf("%s\n", msg->data);
	if(strncmp(msg->data, "login : OK", 10) == 0){
		return 1;
	}else{
		printf("usr not exist or password wrong\n");
		return 0;
	}
}

int TCP_client_sockfd_init(const char *argv1, const char *argv2, struct sockaddr_in *serveraddr)
{
	int ret;
	int sockfd;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(serveraddr, 0, sizeof(struct sockaddr_in));
	
	serveraddr->sin_family = AF_INET;
	serveraddr->sin_addr.s_addr = inet_addr(argv1);
	serveraddr->sin_port = htons(atoi(argv2));

	return sockfd;
}

void check_info(int sockfd,MSG *msg)
{
	int ret;
	  ret = send(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to send\n");
	}

	while(1){
	ret = recv(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to recv\n");
	}
	printf("returnstr:%s\n",msg->data); 
    if(!strncmp(msg->data,"aaa"	,3)){
		printf("sendmsg from server finish\n");
		break;
	} 
	usleep(10);
	}
	return;
}

void Insert_info(int sockfd,MSG *msg)
{
	int ret;
	MENU5;
	  ret = send(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to send\n");
	}

	ret = recv(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to recv\n");
	}
	printf("returnstr:%s\n",msg->data); 
	return;
}

void Delete_info(int sockfd,MSG *msg)
{
	int ret;
	printf("which id you want to be deleted,input id:");
	scanf("%d",&msg->id);
	ret = send(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to send\n");
	}

	ret = recv(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to recv\n");
	}
	printf("returnstr:%s\n",msg->data); 
	return;
}

void Modify_info(int sockfd,MSG *msg)
{
	int item;
	int ret;
	int flag=0;
	printf("whose info you want to change,input id:");
	scanf("%d",&msg->id);
	while(1)
	{
	 MENU6;
	scanf("%d",&item);
	switch(item){
		case 1:                     
		   printf("new age:");
		   scanf("%d",&msg->age);
		   if((msg->age)<=0)
		   {
			   printf("invalid input\n");
		   }
		 break;
		case 2:
		   printf("new wage:");
		   scanf("%d",&msg->wage);
		    if((msg->wage)<=0)
		   {
			   printf("invalid input\n");
		   }
		 break; 
		case 3:
		 flag=1;
		 break;
		default:
		 break;
	}

	if(flag){
		break;
	 }
	}
	ret = send(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to send\n");
	}

	ret = recv(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to recv\n");
	}
	printf("returnstr:%s\n",msg->data); 
	return;
}

void usr_Modify_info(int sockfd,MSG *msg)
{
	int item;
	int ret;
	int flag=0;
	while(1)
	{
		printf("*********************************************\n");
		printf("*which item you want to modify*\n");
		printf("* 1. password  2. age 3.back *\n");
		printf("*********************************************\n");
		printf("which item you want to change,input item:");
	scanf("%d",&item);
	switch(item){
		case 1:                     
		   printf("new password:");
		   scanf("%d",&msg->password);
		 break;
		case 2:
		   printf("new age:");
		   scanf("%d",&msg->age);
		 break; 
		 case 3:
		    flag=1;
		 break;
		default:
		 break;
	  }
	  if(flag)
	  {
		  break;
	  }
	}
	ret = send(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to send\n");
	}

	ret = recv(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to recv\n");
	}
	printf("returnstr:%s\n",msg->data); 
	return;
}

int do_rootfun(int sockfd,MSG *msg)
{
	int ret ;
	int select;
	while(1){
  	MENU4;
	scanf("%d",&select);
	switch(select){
		case 1:                     //查询操作
		    msg->action_type='Q';
         check_info(sockfd,msg);  
		 break;
		 case 2:
		    msg->action_type='I';     
			Insert_info(sockfd,msg);  
		 break;  
		case 3:
		    msg->action_type='D';     
			Delete_info(sockfd,msg);  
		 break; 
		case 4:
		    msg->action_type='M';     //修改信息
			Modify_info(sockfd,msg);  
		 break;  
		 case 5:
		     printf("start to exit\n");
		     close(sockfd);
			exit(EXIT_SUCCESS);
		 break;  
		default:
		printf("invalid input\n");
		break;
	}
  }
	return 0;
}

int do_usrfun(int sockfd,MSG *msg)
{
	int ret ;
	int select;
	while(1){
	MENU7;
	scanf("%d",&select);
	switch(select){
		case 1:                     //查询操作
		    msg->action_type='Q';
         check_info(sockfd,msg);  
		 break;
		case 2:
		    msg->action_type='M'; 
           usr_Modify_info(sockfd,msg);
		 break; 
		case 3:
		     printf("start to exit\n");
		     close(sockfd);
			exit(EXIT_SUCCESS);
		 break;  
		default:
		printf("invalid input\n");
		break;
	}
	}
	return 0;
}

int do_register(int sockfd, MSG *msg){
	
	int ret;
    msg->action_type='R';
	MENU5;
	msg->wage=0;
	
	ret = send(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to send\n");
	}

	ret = recv(sockfd, msg, msglen, 0);
	if(ret < 0){
		err_log("fail to recv\n");
	}

	printf("%s\n", msg->data);
	return 0;
}

int main(int argc, const char *argv[])
{
	int ret;
	char num[N];
	MSG msg;
	int sockfd;
	struct sockaddr_in serveraddr;
	socklen_t addrlen = sizeof(struct sockaddr);

	if(argc != 3){
		printf("Usage: %s ip port\n", argv[0]);
		return -1;
	}

	sockfd = TCP_client_sockfd_init(argv[1], argv[2], &serveraddr);

	ret = connect(sockfd, (struct sockaddr *)&serveraddr, addrlen);
	if(ret < 0){
		err_log("fail to connect\n");	
	}

	while(1){
	  LOOP1:
		MENU1;
		scanf("%s", num);

		memset(&msg, 0, msglen);

		if(!strcmp(num, "1")){
			msg.user_type=1;
			ret=do_login(sockfd, &msg);//root用户
			if(ret==1){
				do_rootfun(sockfd,&msg);
			}else{
				goto LOOP1; //用户不存在或密码不正确，回到LOOP1
			}
			
		}else if(!strcmp(num, "2")){
			msg.user_type=2;
				goto NEXT;
			}
		else if(!strcmp(num, "3")){
			close(sockfd);
			exit(EXIT_SUCCESS);
		}else{
			printf("input error\n");
		}
	}

	while(1){
     NEXT:
		MENU2;
		scanf("%s", num);

		if(!strcmp(num, "1")){
			do_register(sockfd, &msg);  
			ret=do_login(sockfd, &msg);
			if(ret==1)
			{
			  do_usrfun(sockfd,&msg); 	
			}	
		}else if(!strcmp(num, "2")){
			
			ret=do_login(sockfd, &msg); 
			if(ret==1)
			{
			  do_usrfun(sockfd,&msg); 	
			}	
		}else if(!strcmp(num, "3")){
			close(sockfd);
			exit(EXIT_SUCCESS);
		}else{
			printf("input error\n");
		}
	}
	return 0;
}
